/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.ove.openmath.mfd2;

/**
 *
 * @author Mr.Sam
 */
import java.awt.*;
import java.io.*;
import java.net.SocketException;
import fr.ove.openmath.jome.Jome;
import fr.ove.openmath.exceptions.*;
import fr.ove.errordialog.*;
import fr.inria.openmath.omapi.*;
import fr.inria.openmath.omapi.implementation.*;
import fr.ove.openmath.mfd2.PanelMfd2;
import fr.ove.openmath.mfd2.omparser.Mfd2ParserHandler;

public class Selector extends Thread {
    private PanelMfd2 panelMfd2;
    private OpenMathResultSetable jomeOwner;
    
    private InputStream inputStream;
    private XMLParser parser;
    private Mfd2ParserHandler mfd2ParserHandler = new Mfd2ParserHandler();
    
    /**
    * The constructor.
    * @param panelMfd2 where the instance takes the object to select from.
    */
    public Selector(PanelMfd2 panelMfd2, OpenMathResultSetable jomeOwner) {
        this.panelMfd2 = panelMfd2;
        // A l'instanciation, c'est panelMfd2
        this.jomeOwner = jomeOwner;
        inputStream = panelMfd2.getInputStream();
        parser = new XMLParser(mfd2ParserHandler);
    }
    
    public void setOwner(OpenMathResultSetable jomeOwner) {
        this.jomeOwner = jomeOwner;
    }
    
    public void run() {
        String symbol;
        while (true) {
            try {
                parser.initParse(inputStream);
                
                int dispo = 0;
                while ((dispo = inputStream.available()) == 0) {
                    try {
                        Thread.sleep(100);
                    }
                    catch (Exception e) {
                    }
                }
                
                parser.parseObject(inputStream);
                
                jomeOwner.setOpenMathResult(mfd2ParserHandler.getOmObjectParsed());
                
                if (panelMfd2.getCurrentRequest() != jomeOwner)
                    jomeOwner = panelMfd2.getCurrentRequest();
                
            }
            catch (OMException e) {
        	    switch (e.getErrorCode()) {
        	        case OMException.OME_WRAPPING :
        	            try {
        	                if (e.getException() != null) 
            	                throw(e.getException());
            	            else
                	            popError("Error During Parsing", e.getMessage(), mfd2ParserHandler.getOmObjectParsed());
                            
                            try {
                                parser.skipObject(inputStream);
                            }
                            catch (Exception ioe) {
                                ioe.printStackTrace();
                            }
                            
            	                
        	            }
        	            catch (ControlException controlException) {
                    	    symbol = controlException.getSymbol();
                    	    Symbol theSymbol;
                    	    String omObject;
                    	    
                    	    if (symbol.equals("terminated") || symbol.equals("commandOk"))
                    	        panelMfd2.setStatusMessage("< " + controlException.getErrorMessage() + "\n");
                    	    else if (symbol.equals("unhandledSymbol") || symbol.equals("unknownSymbol")) {
                    	        theSymbol = (Symbol) controlException.getDetails();
                    	        omObject = "<OMOBJ>\n  <OMA>\n    <OMS cd=\"control\" name=\"unhandledSymbol\"/>\n    <OMS cd=\"" + theSymbol.getCD() + "\" name=\"" + theSymbol.getName() + "\" />\n  </OMA>\n</OMOBJ>";
                    	        panelMfd2.setObject(omObject.getBytes());
                    	        panelMfd2.setStatusMessage("< " + controlException.getErrorMessage() + " : <OMS cd=\"" + theSymbol.getCD() + "\" name=\"" + theSymbol.getName() + "\" />\n");
                    	        panelMfd2.setStatusMessage("< error message sent\n");
                            }
                            else if (symbol.equals("unknownCD")) {
                    	        theSymbol = (Symbol) controlException.getDetails();
                    	        omObject = "<OMOBJ>\n  <OMA>\n    <OMS cd=\"control\" name=\"unknownCD\"/>\n    <OMSTR>" + theSymbol.getCD() + "</OMSTR>\n  </OMA>\n</OMOBJ>";
                    	        panelMfd2.setObject(omObject.getBytes());
                    	        panelMfd2.setStatusMessage("< " + controlException.getErrorMessage() + " : " + theSymbol.getCD() + "\n");
                    	        panelMfd2.setStatusMessage("< error message sent\n");
                            }
                            else 
                                popError(controlException);
                        }
                    	catch (Mfd2Exception mfd2Exception) {
                	        panelMfd2.setStatusMessage("< " + mfd2Exception.getErrorMessage() + "\n");
                            popError(mfd2Exception);
                        }
                        catch (Exception excep) {
                            excep.printStackTrace();
                        }
                        break;
                        
        	        case OMException.OME_NODE_NOT_FOUND:
        	            popError("OpenMath Node Not Found", e.getMessage(), mfd2ParserHandler.getOmObjectParsed());
                		try {
                		    parser.skipObject(inputStream);
                    	}
                    	catch (Exception ioe) {
                    	    ioe.printStackTrace();
                    	}
        	            break;
        	            
        	        case OMException.OME_SYNTAX:
        	            popError("Syntax Error", e.getMessage(), mfd2ParserHandler.getOmObjectParsed());
                		try {
                		    parser.skipObject(inputStream);
                    	}
                    	catch (Exception ioe) {
                    	    ioe.printStackTrace();
                    	}
        	            break;
        	            
        	        default :
        	            popError("Error During Parsing", e.getMessage(), mfd2ParserHandler.getOmObjectParsed());
                		try {
                		    parser.skipObject(inputStream);
                    	}
                    	catch (Exception ioe) {
                    	    ioe.printStackTrace();
                    	}
                }
        	}
            catch (SocketException se) {
                return; // On a fermé la socket, donc on sort.
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    
    /**
    * Pop up an error dialog window.
    * @param errorMessageException the error message an possible details.
    */
    private void popError(ErrorMessageException errorMessageException) {
        popError("Mfd2 Error", errorMessageException.getErrorMessage(), errorMessageException.getDetails());
    }        

    /**
    * Pop up an error dialog window.
    */
    private void popError(String nameError, String errorMessage, Object details) {
        Container theFrame = panelMfd2;
        while (!(theFrame instanceof Frame))
            theFrame = theFrame.getParent();
        
		ErrorDialog dial = new ErrorDialog((Frame) theFrame, true);
	    Rectangle bounds = theFrame.getBounds();
	    dial.setBounds(bounds.x + bounds.width/2, bounds.y + bounds.height/2, 390,195);
	    
	    dial.setResizable(false);
	    MainPanelError mpe = new MainPanelError(dial, nameError);
	    mpe.setMesg2(errorMessage);
	    if (details != null)
    	    mpe.setDetails(details.toString());
    	    
		dial.addMesg(mpe);
		dial.setVisible(true);
    }        
}






/*
try {
    parser.skipObject(inputStream);
    
    ?? pourquoi parser.skipObject(inputStream) ok et pas ce qui suit ????
    
	int available = inputStream.available();
	while (available > 0) {
	    
	    System.out.println("On skip " + available + " bytes");
	    
	    inputStream.skip(available);
	    available = inputStream.available();
	}
	
}
catch (/*IO*Exception ioe) {
    ioe.printStackTrace();
}
*/
